package linker

import "risc-v/ld/pkg/utils"

// OutPutSectionHeader 主要处理 SectionHeaderTable
// 承担将 SectionHeader 写入到 ELF 文件的 SectionHeaderTable中
// 这里的名字可能会引起一些误解
type OutPutSectionHeader struct {
	Chunk
}

func NewOutPutSectionHeader() *OutPutSectionHeader {
	o := &OutPutSectionHeader{NewChunk()}

	o.SectionHeader.AddrAlign = 8 //64 bits 默认 8 字节对齐
	return o
}

func (o *OutPutSectionHeader) UpdateSectionHeader(ctx *Context) {
	n := uint64(0)
	// 并不是 context 中的所有的 Chunk 都要写入到 SectionHeaderTable
	for _, chunk := range ctx.Chunks {
		if chunk.GetSectionHeaderIndex() > 0 {
			n = uint64(chunk.GetSectionHeaderIndex())
		}
	}

	// 更新SectionHeaderTable的 size 下标从 0 开始 index+1 个 SectionHeader
	// SectionHeaderTable 中的第一个 Section 默认是空
	o.SectionHeader.Size = (n + 1) * uint64(SectionHeaderSize)
}

func (o *OutPutSectionHeader) CopyBuf(ctx *Context) {
	// 找到 SectionHeaderTable 的偏移
	base := ctx.Buf[o.SectionHeader.Offset:]
	utils.Write(base, SectionHeader{})

	// 遍历整个 context的 Chunks 找到需要写入的 SectionHeader
	// 写入输出文件的 SectionHeaderTable 中
	for _, chunk := range ctx.Chunks {
		if chunk.GetSectionHeaderIndex() > 0 {
			utils.Write(base[chunk.GetSectionHeaderIndex()*int64(SectionHeaderSize):],
				*chunk.GetSectionHeader())
		}
	}
}
